package legumes.client.ui.top;

import java.util.ArrayList;
import java.util.List;

import legumes.client.evt.main.ClientsEvent;
import legumes.client.evt.main.MyAccountEvent;
import legumes.client.evt.main.StoreSelectionOverviewEvent;
import legumes.client.evt.main.UserConnectedEvent;
import legumes.client.evt.main.UserConnectedEventHandler;
import legumes.client.evt.main.UserDisconnectedEvent;
import legumes.client.evt.main.UserDisconnectedEventHandler;
import legumes.client.evt.manager.EventBusManager;
import legumes.client.services.callbacks.UnlogCallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.Authentication;
import legumes.client.ui.widgets.list.AbstractListWidget;
import legumes.client.ui.widgets.list.OrderedListWidget;
import legumes.client.ui.widgets.list.item.ComboListItemWidget;
import legumes.client.ui.widgets.list.item.ListItemWidget;
import legumes.shared.domain.CustomerDTO;
import legumes.shared.domain.CustomerRole;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Widget;

public class TopMenuPanel extends HorizontalPanel {
	
	private FlowPanel leftHorizontalPanel;
	private FlowPanel rightHorizontalPanel;
	private FlowPanel middleHorizontalPanel;
	
	private AbstractListWidget leftMenuItemList;
	private AbstractListWidget rightMenuItemList;
	
	private InlineLabel userWelcomeStaticLabel;
	
	private ListItemWidget clientsSeparator;
	private Anchor anchorClients;

	private Widget menuSelectedWidget = null;
	private ListItemWidget myStoresSeparator;
	
	private ComboListItemWidget myStoresComboListItemWidget;
	private MyStoreListWidget myStoresListWidget;
	
	public TopMenuPanel() {
		super();
		setStyleName("topMenuLinkPanel");
		
		leftHorizontalPanel = new FlowPanel();
		initLeftPanelWidgets();
		
		middleHorizontalPanel = new FlowPanel();
		initMiddlePanelWidgets();
		
		rightHorizontalPanel = new FlowPanel();
		initRightPanelWidgets();
		
		add(leftHorizontalPanel);
		setCellWidth(leftHorizontalPanel, "33%");
		setCellHorizontalAlignment(leftHorizontalPanel, HorizontalPanel.ALIGN_LEFT);
		
		add(middleHorizontalPanel);
		setCellWidth(middleHorizontalPanel, "34%");
		setCellHorizontalAlignment(middleHorizontalPanel, HorizontalPanel.ALIGN_CENTER);
		
		add(rightHorizontalPanel);
		setCellWidth(rightHorizontalPanel, "33%");
		setCellHorizontalAlignment(rightHorizontalPanel, HorizontalPanel.ALIGN_RIGHT);
		
		setMenuSelectedWidget( leftMenuItemList.getWidget(0) );
		
		bind();
	}
		
	
	private void initMiddlePanelWidgets(){
		//This panel could be use show an link in order to make undo and re-do actions
	}
	
	private void setMenuSelectedWidget(Widget widgetToSelect_){
		if(widgetToSelect_ != null && widgetToSelect_ instanceof ListItemWidget){
			Widget oldSelWidget;
			if(menuSelectedWidget!=null && menuSelectedWidget instanceof ListItemWidget ){
				ListItemWidget liw = (ListItemWidget)menuSelectedWidget;
				oldSelWidget = liw.getWidget();
				
			} else {
				oldSelWidget = menuSelectedWidget;
			}
			
			if(oldSelWidget!=null){
				oldSelWidget.removeStyleName("inlineMenuListLinkSelected");
			}
			
			ListItemWidget liw = (ListItemWidget)widgetToSelect_;
			Widget selWidget = liw.getWidget();
			if(selWidget!=null){
				menuSelectedWidget = selWidget;
				selWidget.addStyleName("inlineMenuListLinkSelected");
			}
		}
	}

	private InlineLabel createLabelMenuItem(String itemTxt_){
		InlineLabel inlineLabel = new InlineLabel(itemTxt_);
		inlineLabel.setStyleName("inlineMenuListLink");
		return inlineLabel;
	}

	private Anchor createAnchorMenuItem(String itemTxt_, final Command cmd_){
		final Anchor anchor = new Anchor(itemTxt_);
		anchor.setStyleName("inlineMenuListLink");
		anchor.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				setMenuSelectedWidget(anchor);
				cmd_.execute();
			}
		});
		return anchor;
	}
	
	private void initLeftPanelWidgets(){
		List<Widget> menuItemList = new ArrayList<Widget>();
		Widget storeWidget = createAnchorMenuItem("Magasin", new Command() {
			
			@Override
			public void execute() {
				doStoreAction();
			}
		});
		menuItemList.add( storeWidget );
		
		Widget myAccountWidget = createAnchorMenuItem("Mon compte", new Command() {
			
			@Override
			public void execute() {
				doMyAccountAction();
			}
			
		});
		menuItemList.add( myAccountWidget );
		
		leftMenuItemList = new OrderedListWidget();
		leftMenuItemList.setStyleName("inlineMenuListLink");
		leftMenuItemList.setMenu(menuItemList, true);
		leftHorizontalPanel.add(leftMenuItemList);
		
		createClientsMenuItem();
		createMyStoresMenuItem();
	}
	
	private void createClientsMenuItem(){
		clientsSeparator = leftMenuItemList.addSeparator();
		clientsSeparator.setVisible(false);
		anchorClients = createAnchorMenuItem("Clients", new Command() {
			
			@Override
			public void execute() {
				doClientsAction();
			}
		});
		anchorClients.setVisible(false);
		leftMenuItemList.add( anchorClients );
	}
	
	private void createMyStoresMenuItem(){
		myStoresListWidget = new MyStoreListWidget();
		
		myStoresSeparator = leftMenuItemList.addSeparator();
		myStoresSeparator.setVisible(false);
		
		myStoresComboListItemWidget = new ComboListItemWidget("Mes magasins", myStoresListWidget){
			@Override
			protected void setAnchorStyleName(Anchor anchor_){
				anchor_.setStyleName("inlineMenuListLink");
			}
		};
		myStoresComboListItemWidget.setVisible(false);
		leftMenuItemList.add( myStoresComboListItemWidget );
	}


	private void initRightPanelWidgets(){
		List<Widget> menuItemList = new ArrayList<Widget>();
		userWelcomeStaticLabel = createLabelMenuItem( "Bienvenue !" );
		menuItemList.add( userWelcomeStaticLabel );
		
		Widget logoutWidget = createAnchorMenuItem("Déconnexion", new Command() {
			
			@Override
			public void execute() {
				doLogoutAction();
			}
		});
		menuItemList.add( logoutWidget );
		
		rightMenuItemList = new OrderedListWidget();
		rightMenuItemList.setStyleName("inlineMenuListLink");
		rightMenuItemList.setMenu(menuItemList, false);
		
		rightHorizontalPanel.add(rightMenuItemList);
		rightHorizontalPanel.setVisible(false);
	}
	
	protected void doStoreAction() {
		EventBusManager.getInstance().getEventBus().fireEvent(new StoreSelectionOverviewEvent());
	}

	protected void doMyAccountAction() {
		EventBusManager.getInstance().getEventBus().fireEvent(new MyAccountEvent());
	}

	private void bind(){

		EventBusManager.getInstance().getEventBus().addHandler(
				UserConnectedEvent.TYPE, 
				new UserConnectedEventHandler(){

					@Override
					public void onUserConnected(UserConnectedEvent event) {
						TopMenuPanel.this.onUserConnected(event.getCustomerDTO());
					}
				});
		
		EventBusManager.getInstance().getEventBus().addHandler(
				UserDisconnectedEvent.TYPE, 
				new UserDisconnectedEventHandler(){

					@Override
					public void onUserDisconnected(UserDisconnectedEvent event) {
						TopMenuPanel.this.onUserDisconnected(event.getCustomerDTO());
					}
				});
	}
	
	protected void onUserDisconnected(CustomerDTO customer_) {
		rightHorizontalPanel.setVisible(false);
		userWelcomeStaticLabel.setText("Bienvenue !");
		
		showClientsMenuItem();
		showMyStoresMenuItem();
	}
	
	private void onUserConnected(CustomerDTO customer_){
		rightHorizontalPanel.setVisible(true);
		userWelcomeStaticLabel.setText("Bienvenue " + customer_.getName() + " !");

		myStoresListWidget.reloadData();
		
		showClientsMenuItem();
		showMyStoresMenuItem();
	}
	
	private void showMyStoresMenuItem() {
		boolean showMyStores = Authentication.getCustomer() != null;
		myStoresComboListItemWidget.setVisible(showMyStores);
		myStoresSeparator.setVisible(showMyStores);
	}


	private void showClientsMenuItem(){
		boolean isAsmin = Authentication.getCustomer() != null 
			&& Authentication.getCustomer().getRolesAsEnum().equals(CustomerRole.ADMINISTRATOR);
		clientsSeparator.setVisible(isAsmin);
		anchorClients.setVisible(isAsmin);
	}
	
	protected void doClientsAction() {
		EventBusManager.getInstance().getEventBus().fireEvent(new ClientsEvent());
	}

	private void doLogoutAction(){
		final RPCCallSequencer callSequencer = new RPCCallSequencer();
		callSequencer.addCall(new UnlogCallback());
		callSequencer.addRunnable(new Runnable() {
			public void run() {
				EventBusManager.getInstance().getEventBus().fireEvent(
						new UserDisconnectedEvent(Authentication.getCustomer()));
				Authentication.setCustomer(null);
				rightMenuItemList.setVisible(false);
				
				setMenuSelectedWidget(leftMenuItemList.getWidget(0));
				doStoreAction();
			}
		});
		callSequencer.callSequence();
	}
}
